import os
import sys
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import *
from PyQt5 import uic
from loguru import logger

from com.SSHConCore import SSHConByPy
from com.Linux.CPUMsg import CPUMsg
from com.Linux.LoadMsg import LoadMsg
from com.Linux.DiskSpaceMsg import DiskSpaceMsg
from com.Linux.MemoryMsg import MemoryMsg
from com.UseCOMMAND import UseCOMMAND


class EnterUiMain(QWidget):

    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        self.ui = uic.loadUi("./UiMain.ui")
        print(self.ui.__dict__)  # 查看ui文件中有哪些控件
        # 日志
        self.logDir = os.path.expanduser('./logs')
        self.logFile = os.path.join(self.logDir, 'linuxma_log_{time}.log')
        if not os.path.exists(self.logDir):
            os.mkdir(self.logDir)
        logger.add(self.logFile, rotation="200 KB", compression="zip", retention="0.5h")
        # 获取控件信息
        # 登录控件
        self.login_ip = self.ui.input_IP
        self.login_username = self.ui.input_username
        self.login_pwd = self.ui.input_pwd
        self.login_button = self.ui.B_login
        self.exit_button = self.ui.B_exit
        self.exit_button.setEnabled(False)
        self.login_button.clicked.connect(self.login)
        self.exit_button.clicked.connect(self.exit)
        # 负载均衡控件
        self.bl_5min = self.ui.label_Balance_5min
        self.bl_10min = self.ui.label_Balance_10min
        self.bl_15min = self.ui.label_Balance_15min
        # cpu控件
        self.cpu_num = self.ui.label_CPU_num
        self.cpu_fac = self.ui.label_CPU_fac
        self.cpu_ver = self.ui.label_CPU_ver
        self.cpu_name = self.ui.label_CPU_name
        # 基本信息控件
        self.base_OS_name = self.ui.label_OS_name
        self.base_OS_class = self.ui.label_OS_class
        self.base_OS_time = self.ui.label_OS_time
        self.base_OS_user = self.ui.label_OS_user
        self.base_OS_thread_total = self.ui.label_OS_thread_total
        self.base_OS_thread_usingNum = self.ui.label_OS_thread_usingNum
        self.base_OS_thread_using_processID = self.ui.label_OS_thread_usingId
        # 容量信息控件
        self.cap_label_MEM_total = self.ui.label_MC_t_var
        self.cap_label_MEM_free = self.ui.label_MC_u_var
        self.cap_label_MEM_progress = self.ui.Mem_progressBar
        self.cap_label_DISK_total = self.ui.label_DC_t_var
        self.cap_label_DISK_free = self.ui.label_DC_u_var
        self.cap_label_DISK_progress = self.ui.Disk_progressBar

    def exit(self):
        try:
            # 退出成功 设置为可修改
            self.login_ip.setReadOnly(False)
            self.login_username.setReadOnly(False)
            self.login_pwd.setReadOnly(False)
            logger.success('成功 => 输入框被设置为只读')
            # 退出成功 设置为可用
            self.login_button.setEnabled(True)
            self.exit_button.setEnabled(False)
            logger.success('成功 => 退出按钮被设置为禁用，登录按钮设置为启用')
            # 关闭连接
            self.client.close_connect()
            logger.success('成功 => ssh关闭成功')
            # 负载均衡控件
            self.bl_5min.setText('0.0')
            self.bl_10min.setText('0.0')
            self.bl_15min.setText('0.0')
            logger.success('成功 => 均衡负载模块被重置')
            # cpu控件
            self.cpu_num.setText('')
            self.cpu_fac.setText('')
            self.cpu_ver.setText('')
            self.cpu_name.setText('')
            logger.success('成功 => CPU模块被重置')
            # 基本信息控件
            self.base_OS_name.setText('')
            self.base_OS_class.setText('')
            self.base_OS_time.setText('')
            self.base_OS_user.setText('')
            self.base_OS_thread_total.setText('')
            self.base_OS_thread_usingNum.setText('')
            self.base_OS_thread_using_processID.setText('')
            logger.success('成功 => 基本信息模块被重置')
            # 容量信息控件
            self.cap_label_MEM_total.setText('0.0MB')
            self.cap_label_MEM_free.setText('0.0MB')
            self.cap_label_MEM_progress.setValue(0)
            self.cap_label_DISK_total.setText('0.0MB')
            self.cap_label_DISK_free.setText('0.0MB')
            self.cap_label_DISK_progress.setValue(0)
            logger.success('成功 => 容量信息模块被重置')
        except Exception as err:
            logger.error("退出失败 => {log_err}", log_err=err)
            logger.exception("退出异常")

    def login(self):
        ip = self.login_ip.text()
        username = self.login_username.text()
        pwd = self.login_pwd.text()

        # 登录各个客户端
        try:
            self.client = SSHConByPy(ip, 22, username, pwd)
            self.COMMAND_client = UseCOMMAND(ip, 22, username, pwd)
            self.CPU_client = CPUMsg(ip, 22, username, pwd)
            self.LOAD_client = LoadMsg(ip, 22, username, pwd)
            self.DISK_client = DiskSpaceMsg(ip, 22, username, pwd)
            self.MEM_client = MemoryMsg(ip, 22, username, pwd)
            # 登录成功 设置为不可修改
            self.login_ip.setReadOnly(True)
            self.login_username.setReadOnly(True)
            self.login_pwd.setReadOnly(True)
            # 登录成功 设置为禁用
            self.login_button.setEnabled(False)
            # 连接成功 设置为可用
            self.exit_button.setEnabled(True)
            # 写入日志
            logger.success('登录成功 => ip:{log_ip}    username:{log_username}', log_ip=ip, log_username=username)
            try:
                # 负载均衡监控
                self.loadBalance()
                logger.success('成功 => 负载均衡加载成功')
                # CPU信息
                self.CpuINFO()
                logger.success('成功 => CPU信息加载成功')
                # 基本信息
                self.baseINFO()
                logger.success('成功 => 基本信息加载成功')
                # 容量信息
                self.capacityINFO()
                logger.success('成功 => 容量信息加载成功')
            except Exception as err:
                # 写入日志
                logger.error("加载失败 => {log_err}", log_err=err)
                logger.exception("异常")
        except Exception as err:
            # 写入日志
            logger.error('登录失败：' + str(err))
            logger.exception('登录异常')

    def loadBalance(self):
        self.bl_5min.setText(self.LOAD_client.get_thrLoadAvgs()[0])
        self.bl_10min.setText(self.LOAD_client.get_thrLoadAvgs()[1])
        self.bl_15min.setText(self.LOAD_client.get_thrLoadAvgs()[2])

    def CpuINFO(self):
        num = self.CPU_client.get_count_CPUNum()
        self.cpu_num.setText(str(num))
        self.cpu_fac.setText(self.CPU_client.get_detailedCPUMsg_en()['vendor_id'])
        self.cpu_ver.setText(self.CPU_client.get_detailedCPUMsg_en()['cpu family'])
        self.cpu_name.setText(self.CPU_client.get_detailedCPUMsg_en()['model name'])

    def baseINFO(self):
        os_info = {}
        # .strip('\t\n') 为了防止获取的值有换行和空格 会使得前端展示不完整
        self.base_OS_name.setText(self.COMMAND_client.get_message('hostname').strip('\n'))
        line_info = self.COMMAND_client.get_message_line('lsb_release -a')
        for line in line_info:
            ls_line = line.strip('\t').split(':')
            ls_line[0] = ls_line[0].strip('\t')
            # 由于上一步的处理 在获取key值的时候发现 有列表只有一个元素 且为 ''  故判断  否则会报错：列表下标溢出
            if ls_line[0] != '':
                os_info[ls_line[0]] = ls_line[1]
        # print(os_info['Description'].strip('\t\n'))
        self.base_OS_class.setText(os_info['Description'].strip('\t\n'))
        os_time = self.COMMAND_client.get_message('cat /proc/uptime')
        line_os_time = os_time.split(' ')
        base_os_time = str(round(float(line_os_time[0]) / 3600, 2)) + '小时'
        self.base_OS_time.setText(base_os_time)
        self.base_OS_user.setText(self.COMMAND_client.get_message('whoami').strip('\t\n'))
        self.base_OS_thread_total.setText(str(self.LOAD_client.get_threadCount()[0]).strip('\t\n'))
        self.base_OS_thread_usingNum.setText(str(self.LOAD_client.get_threadCount()[1]).strip('\t\n'))
        self.base_OS_thread_using_processID.setText(str(self.LOAD_client.get_usingProcess_id()).strip('\t\n'))

    def capacityINFO(self):
        self.cap_label_MEM_total.setText(str(self.MEM_client.get_computeRAMemory()[0]).strip('\n\t') + 'MB')
        self.cap_label_MEM_free.setText(str(self.MEM_client.get_computeRAMemory()[1]).strip('\n\t') + 'MB')
        self.cap_label_MEM_progress.setValue(self.MEM_client.get_computeRAMemory()[2] * 100)
        # 获取磁盘信息  返回一个二维数组
        disk_ls = self.diskINFO()
        # 总空间大小
        size_sum = 0
        avail_sum = 0
        for i in range(1, len(disk_ls)):
            size_sum += (int(disk_ls[i][1]) / 1024)
        size_sum = round(size_sum, 2)
        # 可用空间大小
        for i in range(1, len(disk_ls)):
            avail_sum += (int(disk_ls[i][3]) / 1024)
        avail_sum = round(avail_sum, 2)
        # 计算占比 可用/总
        cent = round(avail_sum / size_sum, 2)
        self.cap_label_DISK_total.setText(str(size_sum).strip('\t\n') + 'MB')
        self.cap_label_DISK_free.setText(str(avail_sum).strip('\t\n') + 'MB')
        self.cap_label_DISK_progress.setValue(cent * 100)

    def diskINFO(self):
        ls = self.COMMAND_client.get_message("df")
        line = ls.split('\n')
        l_2 = []
        for i in range(len(line)):
            l1 = line[i].split(' ')
            # 排空
            while '' in l1:
                l1.remove('')
            # 删除多余
            if i == 0:
                l1.pop()
            # 排空
            if len(l1) < 2:
                continue
            l_2.append(l1)
        return l_2


if __name__ == '__main__':
    app = QApplication(sys.argv)

    w = EnterUiMain()
    w.ui.setWindowIcon(QIcon("./4417102_desktop_pc_server_icon.ico"))
    w.ui.setWindowTitle("服务器监控")

    # 展示窗口
    w.ui.show()

    app.exec()
